const Round =qguan(0,"Round")
const Block =qguan(0,"Block")
const Row =qguan(0,"Row")
const Dar =qguan(0,"Dar")
const AnalogyChange =qguan(0,"AnalogyChange")
function isPromise(obj) {
    return !!obj  //有实际含义的变量才执行方法，变量null，undefined和''空串都为false
        && (typeof obj === 'object' || typeof obj === 'function') // 初始promise 或 promise.then返回的
        && typeof obj.then === 'function';
}

export default class Execute{


    constructor(pThis){
        this.queue=[];


        this.pThis=pThis;
        this.codePointer=1;
        this.dataPointer=new Row(0,0,0,0);
        this.temPointer=new Row(0,0,0,0);
        this.stack=new Array();
        this.temData=new Round();
        this.ambient=0; //环境
    }

    next(){
        let _this=this;
        if (_this.codePointer<_this.code.list[0].list.length+1 &&_this.stack.length<=0) {
            if (_this.codePointer > _this.code.list[0].list.length) {
                _this.pop(); //退栈
                _this.codePointer++;
            }

            let row=_this.code.findData(0,0,null,_this.func.bind(_this))
            let a1=row.find(1);
            let a2=row.find(2);
            let a3=row.find(3);
            let a4=row.find(4);

            switch (a4){
                case '0': // 对象
                    break;
                case '1': //结构
                    _this.structure(a1,a2,a3,a4);
                    break;
                case '2': //动作
                    _this.operate(a1,a2,a3,a4);
                    break;
                default : // 入栈调用别的程序
                    _this.push(a1,a2,a3,a4);
                    break;
            }


            _this.codePointer++
        }

        if(_this.ambient==0){
            let res =new Array();
            res.push(this.code)
            res.push(this.temData)
            res.push(null)
            res.push(this.ambient)
            return res
        }

    }

    /**
     * 运行
     * @param code
     * @param ambient
     */
    run(a,b,c,d){
        let _this=this;
        //获取代码 创建新环境
        let codeBocik=this.pThis.findReal(null,d);
        let codeRound=AnalogyChange.toRound(codeBocik);

        this.codePointer=1;
        this.dataPointer=new Row(0,0,0,0);
        this.temPointer=new Row(0,0,0,0);
        this.code=codeRound;
        this.temData=new Round();
        _this.next()
    }


    /**
     * 调用外部程序
     */
    callRun(a,b,c,d){
        let obj=this.temData.list[a]
        let res =this.pThis.dataHub.emitRes(d,obj);
        if(isPromise(res)){

            res.then((re)=>{
                if(b&&re){
                    this.temData.list[b]=re;
                }
                this.next();
            })

        }else {
            if(b&&res){
                this.temData.list[b]=res;
            }
            this.next();
        }
    }

    /**
     * 获取一条指令
     * @param RoundId
     * @param BlockId
     * @param RowId
     * @param dataThis
     */
    func(RoundId,BlockId,RowId,dataThis){
        return   dataThis.list[this.codePointer-1]
    }

    /**
     * 结构
     */
    structure(){
        //读取解析参数
        let part= this.code.list[this.codePointer];
        //有没有条件
        let ifPointer=0;
        let ifRow=null
        let isIf=false;
        for(let i=0;i<part.list.length;i++){
            let row=part.list[i];
            if(row.isValue(4,"1")){ //对比方式
                contrastType=row;
                continue;
            }
            if(row.isValue(4,"2")){ //参数 库
                param=row;
                continue;
            }
            if(row.isValue(4,"3")){ //参数位置
                param=row;
                continue;
            }
            if(row.isValue(4,"4")){ //源 库
                resType=row;
                continue;
            }
            if(row.isValue(4,"5")){ //源 位置
                resType=row;
                continue;
            }
            if(row.isValue(3,"6")){ //有条件跳转
                ifRow=row;
                continue;
            }
            if(row.isValue(3,"7")){//无条件跳转
                ifPointer=row.find(1)
                continue;
            }
        }

        if(isIf){ //执行判断
            if(ifRow){
                if(this.isIf()){ //条件判断
                    ifPointer=ifRow.find(2)
                }else {
                    ifPointer=ifRow.find(1)
                }
            }
        }
        if(ifPointer===0){
            this.codePointer=this.code.length;
        }else {

            this.codePointer=ifPointer;
        }


        //跳转

        this.next();

    }
    isIf(){

        return true;
    }
    /**
     * 操作
     *  参数类型
     *  返回值类型
     *  操作数据
     */
    operate(a1,a2,a3,a4){

        //读取解析参数
        let part= this.code.list[this.codePointer];

        //条件
        //有没有条件
        let resType=null; //返回类型
        let ergodic=null; //遍历方式
        let contrastType=null;//对比方式
        let param=null;//参数位置

        let paramRound=null;//参数位置
        let source=null;//源

        let sourceRound="0";//
        let target=null;//目标
        let targetRound="2";
        for(let i=0;i<part.list.length;i++){
            let row=part.list[i];
            if(row.isValue(4,"1")){ //对比方式
                this.contrastType=row;
                continue;
            }
            if(row.isValue(4,"2")){ //参数 库
                this.paramRound=row;
                continue;
            }
            if(row.isValue(4,"3")){ //参数位置
                this. param=row;
                continue;
            }
            if(row.isValue(4,"4")){ //源 库
                sourceRound=row.find(1);
                continue;
            }
            if(row.isValue(4,"5")){ //源 位置
                source=row;
                continue;
            }

            if(row.isValue(4,"6")){ //目标 库
                targetRound=row.find(1);
                continue;
            }
            if(row.isValue(4,"7")){ //目标位置
                this. target=row;
                continue;
            }
            if(row.isValue(4,"8")){//遍历方式
                this. ergodic=row;
                continue;
            }

        }

        /**
         *参数类型和位置
         */
        switch (param){

        }

        /**
         * 原数据执行查询
         */
        let res;
        if(!source){
            source=new Row(0,0,0,0)
        }
        switch (sourceRound){

            case "1":{
                res= this.pThis.findData(source.find(1),source.find(2),source.find(3),this.tree.bind(this));
                break
            }
            case "2":{
                break
            }
            case "3":{
                break
            }
            case "4":{
                break
            }
            default:{
                res=   this.pThis.findData(source.find(1),source.find(2),source.find(3),this.tree.bind(this));
            }

        }
        /**
         * 目标
         */
        if(!target){
            target=new Row(0,0,0,0)
        }
        switch (targetRound){
            case "1":{
                this.saveData(target.find(1),target.find(2),target.find(3),res);
                break
            }
            case "2":{
                this.pThis.saveOutType(res);
                break
            }

            default:{
                this.temData.saveData(target.find(1),target.find(2),target.find(3),res);
                break
            }
        }

        this.next();

    }

    tree(fileId,blockId,rowId,dataThis){

        return      dataThis.list[1];
    }


    collExe(a1,a2,a3,a4){
        switch (a3){
            case "0": //内部程序
                this. push(a1,a2,a3,a4)
                break;

            case "1": //
                break
            default: //外部程序
                this.callRun(a1,a2,a3,a4)

                break;
        }
        this.next();
    }

    /**
     *            13  入栈
     **/
    push(a1,a2,a3,a4){

        // 保存环境到栈里面
        let environment={};
        environment.codePointer=this.codePointer;
        environment.dataPointer=this.dataPointer;
        environment.temPointer=this.temPointer;
        environment.code=this.code;
        environment.temData=this.temData;
        this.stack.push(environment);

        //获取代码 创建新环境
        let codeBocik=this.pThis.findReal(null,'44');
        let codeRound=AnalogyChange.toRound(codeBocik);

        this.codePointer=1;
        this.dataPointer=new Row(0,0,0,0);
        this.temPointer=new Row(0,0,0,0);
        this.code=codeRound;
        this.temData=new Round();

    }
    /**
     * 1           14 弹出栈
     **/
    pop(a1,a2,a3){
        let environment=  this.stack[this.stack.length-1]
        let temData=this.temData;

        this.codePointer=environment.codePointer;
        this.dataPointer=environment.dataPointer;
        this.temPointer=environment.temPointer;
        this.code=environment.code;
        this.temData=environment.temData;

        //把执行结果，还原栈环境
        let res= temData.list[temData.list.length-1];
        this.next();

    }

    /**
     *  返回值 处理
     * @param a1
     * @param a2
     * @param a3
     */
    code15(a1,a2,a3){

    }

}